<?php
/**
 * Created by PhpStorm.
 * User: Monkey
 * Date: 2021/10/13
 * Time: 11:27
 * Desc: 菜单
 */
declare (strict_types=1);

namespace app\backend\controller;

use app\backend\base\controller\Base;
use app\backend\validate\MenuValidate;
use think\facade\Db;

class Menu extends Base
{
    /**
     * 列表
     */
    public function index()
    {
        if (request()->isPost()) {
            $fieldName = input('field_name', '');
            $fieldValue = input('field_value', '');

            //条件
            $where = [];

            //字段筛选
            if (!empty($fieldName) && !empty($fieldValue)) {
                switch ($fieldName) {
                    case 'name'://菜单名称
                        $where[] = ['name', '=', $fieldValue];
                        break;
                }
            }

            $menuArr = \app\extend\model\Menu::where($where)->order(['sort' => 'asc','id' => 'asc'])->select()->toArray();

//            foreach ($menuArr as &$menuVal) {
//                if ($menuVal['parent_id'] == 0) {
//                    $menuVal['open'] = true;
//                }
//            }

            return json([
                'code' => 0,
                'msg' => '获取成功',
                'data' => $menuArr,
            ])->send();
        } else {
            return view('index');
        }
    }

    /**
     * 添加
     */
    public function add()
    {
        if (request()->isPost()) {
            $validate = new MenuValidate();
            $ret = $validate->scene('add')->check(input());
            if(!$ret){
                return json(_E($validate->getError()));
            }

            $name = input('name', '');
            $type = input('type/d', 0);
            $m = strtolower(input('m', ''));
            $c = strtolower(input('c', ''));
            $a = strtolower(input('a', ''));
            $icon = input('icon', '');
            $sort = input('sort/d', 0);
            $parentId = input('parent_id/d', 0);
            $isShow = input('is_show/d', 1);

            $result = \app\extend\model\Menu::insert([
                'name' => $name,
                'type' => $type,
                'm' => $m,
                'c' => $c,
                'a' => $a,
                'icon' => $icon,
                'sort' => $sort,
                'parent_id' => $parentId,
                'is_show' => $isShow,
                'created_at' => date('Y-m-d H:i:s'),
                'updated_at' => date('Y-m-d H:i:s')
            ]);

            if (!$result) {
                return json(_E('添加失败'));
            } else {
                return json(_S('添加成功'));
            }
        }
    }

    /**
     * 修改
     */
    public function edit()
    {
        if (request()->isPost()) {
            $validate = new MenuValidate();
            $ret = $validate->scene('edit')->check(input());
            if(!$ret){
                return json(_E($validate->getError()));
            }

            $id = input('id/d', 0);
            $name = input('name', '');
            $type = input('type/d', 0);
            $m = strtolower(input('m', ''));
            $c = strtolower(input('c', ''));
            $a = strtolower(input('a', ''));
            $icon = input('icon', '');
            $sort = input('sort/d', 0);
            $parentId = input('parent_id/d', 0);
            $isShow = input('is_show/d', 1);

            //获取所有的子类ID
            if ($type == 0) {
                $idArr = $this->_findSon($id);
            } else {
                $idArr = $this->_findParent($id);
            }

            try {
                // 启动事务
                Db::startTrans();
                //修改数据
                \app\extend\model\Menu::where([['id', '=', $idArr[0]]])->update([
                    'name' => $name,
                    'type' => $type,
                    'm' => $m,
                    'c' => $c,
                    'a' => $a,
                    'icon' => $icon,
                    'sort' => $sort,
                    'parent_id' => $parentId,
                    'is_show' => $isShow,
                    'updated_at' => date('Y-m-d H:i:s')
                ]);

                //所有子类状态变成隐藏
                \app\extend\model\Menu::where([['id', 'in', $idArr]])->update([
                    'is_show' => $isShow
                ]);

                Db::commit();
                return json(_S('修改成功'));
            } catch (\Exception $e) {
                Db::rollback();
                return json(_E('修改失败,错误:' . $e->getMessage()));
            }
        }
    }

    /**
     * 删除
     */
    public function del()
    {
        if (request()->isPost()) {
            $validate = new MenuValidate();
            $ret = $validate->scene('del')->check(input());
            if(!$ret){
                return json(_E($validate->getError()));
            }

            $id = input('id/d', 0);

            //获取所有的子类ID
            $idArr = $this->_findSon($id);

            $result = \app\extend\model\Menu::where([
                ['id', 'in', $idArr]
            ])->delete();
            if (!$result) {
                return json(_E('删除失败'));
            } else {
                return json(_S('删除成功'));
            }
        }
    }

    /**
     * 根据菜单ID获取下面所有子类ID
     * @param int $id
     * @return int[]
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function _findSon($id = 0)
    {
        $idArr = [$id];

        $result = [$id];

        while (true) {
            $menuArr = \app\extend\model\Menu::where([
                ['parent_id', 'in', $idArr]
            ])->field('id')->select()->toArray();
            if (empty($menuArr)) {
                break;
            }
            $tmp = [];
            foreach ($menuArr as $menuVal) {
                $tmp[] = $menuVal['id'];
                $result[] = $menuVal['id'];
            }
            $idArr = $tmp;
        }

        return $result;
    }

    /**
     * 根据菜单ID获取下面所有父类ID
     * @param int $id
     * @return int[]
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\DbException
     * @throws \think\db\exception\ModelNotFoundException
     */
    private function _findParent($id = 0)
    {
        $idArr = [$id];

        $result = [$id];

        while (true) {
            $menuArr = \app\extend\model\Menu::where([
                ['id', 'in', $idArr]
            ])->field('parent_id')->select()->toArray();
            if (empty($menuArr)) {
                break;
            }
            $tmp = [];
            foreach ($menuArr as $menuVal) {
                $tmp[] = $menuVal['parent_id'];
                $result[] = $menuVal['parent_id'];
            }
            $idArr = $tmp;
        }

        return $result;
    }
}
